package org.jbpm.leave.action;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipInputStream;

import javax.servlet.ServletOutputStream;

import org.apache.struts2.ServletActionContext;
import org.jbpm.api.ExecutionService;
import org.jbpm.api.ProcessDefinition;
import org.jbpm.api.ProcessEngine;
import org.jbpm.api.ProcessInstance;
import org.jbpm.api.RepositoryService;
import org.jbpm.api.TaskService;
import org.jbpm.api.model.ActivityCoordinates;
import org.jbpm.api.task.Task;
import org.jbpm.leave.util.JbpmUtils;
import org.jbpm.leave.vo.ProcessVo;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class JbpmAction extends ActionSupport {

	private ProcessEngine processEngine;
	private RepositoryService repositoryService;
	private ExecutionService executionService;
	private TaskService taskService;
	private String id;
	private List<ProcessDefinition> processDefinitionList;
	private List<ProcessInstance> processInstanceList;
	private List<Task> taskList;
	private ActivityCoordinates ac;
	private ProcessVo processVo;
	private Map<String, Object> map;
	private String result;

	public void setId(String id) {
		this.id = id;
	}

	public String getId() {
		return id;
	}

	public ActivityCoordinates getAc() {
		return ac;
	}

	public List<ProcessInstance> getProcessInstanceList() {
		return processInstanceList;
	}

	public List<Task> getTaskList() {
		return taskList;
	}

	private void init() {
		processEngine = JbpmUtils.getProcessEngine();
		repositoryService = processEngine.getRepositoryService();
		executionService = processEngine.getExecutionService();
		taskService = processEngine.getTaskService();
	}

	public List<ProcessDefinition> getProcessDefinitionList() {
		return processDefinitionList;
	}

	private String userName;

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String login() {
		Map<String, Object> map = ActionContext.getContext().getSession();
		map.put("user", userName);
		return SUCCESS;
	}


	public String loadIndexPage() {
		init();
		processDefinitionList = repositoryService
				.createProcessDefinitionQuery().list();
		processInstanceList = executionService.createProcessInstanceQuery()
				.list();

		String manager = "zwllxs1,zwllxs2,zwllxs3,zwllxs4";
		String boss = "zhangweilin,zhangweilin2,zhangweilin3,zhangweilin4";
		String roleName = "";

		String name = getLoginedUserName();


		if (manager.contains(name)) {
			roleName = "manager";
		}

		else if (boss.contains(name)) {
			roleName = "boss";
		}

		else {
			roleName = name;
		}

		System.out.println("roleName: " + roleName);
		taskList = taskService.findPersonalTasks(roleName);
		System.out.println("taskList: " + taskList);
		return SUCCESS;
	}

	public String deploy() {
		System.out.println("Initialize the process...");
//		init();
//		// String
//		// did=repositoryService.createDeployment().addResourceFromClasspath("leave2.jpdl.xml").deploy();
//		ZipInputStream zis = new ZipInputStream(this.getClass()
//				.getResourceAsStream("/leave2.zip"));
//		String did = repositoryService.createDeployment()
//				.addResourcesFromZipInputStream(zis).deploy();
//
//		System.out.println("did: " + did);
		return SUCCESS;
	}

	public String start() {
		init();
		Map<String, String> map = new HashMap<String, String>();
		map.put("owner", getLoginedUserName());
		System.out.println("id_: " + id);
		ProcessInstance processInstance = executionService
				.startProcessInstanceById(id, map);
		System.out.println("processInstance: " + processInstance.getId());
		return SUCCESS;
	}

	/**
	 * 
	 * @return
	 */
	public String manager() {
		init();
		Task task = taskService.getTask(id);
		String taskId = task.getId();
		Set<String> strSet = new HashSet<String>();
		strSet.add("owner");
		strSet.add("day");
		strSet.add("reason");
		strSet.add("name");
		strSet.add("sex");
		strSet.add("age");
		map = taskService.getVariables(taskId, strSet);
		System.out.println("map: " + map);
		return SUCCESS;
	}


	public String boss() {
		init();
		Task task = taskService.getTask(id);
		String taskId = task.getId();
		Set<String> strSet = new HashSet<String>();
		strSet.add("owner");
		strSet.add("day");
		strSet.add("reason");
		strSet.add("name");
		strSet.add("sex");
		strSet.add("age");
		// taskService.getVariable(taskId, "owner");
		map = taskService.getVariables(taskId, strSet);
		return SUCCESS;
	}


	public String submitBoss() {
		init();
		taskService.completeTask(id);
		return SUCCESS;
	}


	public String submitManager() {
		init();
		taskService.completeTask(id, result);
		return SUCCESS;
	}


	public String remove() {
		init();
		repositoryService.deleteDeploymentCascade(id);
		return SUCCESS;
	}

	public String view() {
		init();
		ProcessInstance processInstance = executionService
				.findProcessInstanceById(id);
		Set<String> activityNames = processInstance.findActiveActivityNames();

		ac = repositoryService.getActivityCoordinates(processInstance
				.getProcessDefinitionId(), activityNames.iterator().next());
		return SUCCESS;
	}

	public void pic() throws IOException {
		init();
		ProcessInstance processInstance = executionService
				.findProcessInstanceById(id);
		String processDefinitionId = processInstance.getProcessDefinitionId();
		ProcessDefinition processDefinition = repositoryService
				.createProcessDefinitionQuery()
				.processDefinitionId(processDefinitionId).uniqueResult();
		String filePath = "leave2.png";
		InputStream inputStream = repositoryService.getResourceAsStream(
				processDefinition.getDeploymentId(), filePath);
		byte[] b = new byte[1024];
		int len = -1;
		ServletOutputStream sos = ServletActionContext.getResponse()
				.getOutputStream();
		while ((len = inputStream.read(b, 0, 1024)) != -1) {
			sos.write(b, 0, len);
		}
		sos.close();
	}

	public String submit() {
		init();
		Map<String, String> map = new HashMap<String, String>();
		map.put("day", processVo.getDay());
		map.put("reason", processVo.getReason());
		map.put("name", processVo.getOwner());
		map.put("age", processVo.getAge());
		map.put("sex", processVo.getSex());
		System.out.println("Complete the task...");
		taskService.completeTask(processVo.getTaskId(), map);
		return SUCCESS;
	}

	public String getLoginedUserName() {
		return (String) ActionContext.getContext().getSession().get("user");
	}


	/**
     * 
     */
	private static final long serialVersionUID = 7726442371304781094L;

	public ProcessVo getProcessVo() {
		return processVo;
	}

	public void setProcessVo(ProcessVo processVo) {
		this.processVo = processVo;
	}

	public Map<String, Object> getMap() {
		return map;
	}

	public String getResult() {
		return result;
	}

	public void setResult(String result) {
		this.result = result;
	}

}
